Preact is a front end web framework that’s similar to React.
It’s smaller and less complex than React.
In this article, we’ll look at how to get started with front end development with Preact.
Web Components
We can render web components in our Preact component.
For example, we can write:
import { Component, render } from "preact";
window.customElements.define(
"x-foo",
class extends HTMLElement {
constructor() {
super();
let tmpl = document.createElement("template");
tmpl.innerHTML = `
<b>I am in the shadown dom</b>
<slot></slot>
`;
let shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(tmpl.content.cloneNode(true));
}
}
);
export default class App extends Component {
render() {
return <x-foo position={{ x: 10, y: 20 }}>foo bar</x-foo>;
}
}
if (typeof window !== "undefined") {
render(<App />, document.getElementById("root"));
}
We call customElements.define
to create our web component.
Then we reference it in the App
component and add our content inside the slot
.
We can use the x
and y
properties by writing:
import { Component, render } from "preact";
window.customElements.define(
"x-foo",
class extends HTMLElement {
constructor() {
super();
let tmpl = document.createElement("template");
tmpl.innerHTML = `
<b>I am in the shadown dom</b>
<slot></slot>
`;
let shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(tmpl.content.cloneNode(true));
}
set position({ x, y }) {
this.style.cssText = `left:${x}px; top:${y}px; position: absolute`;
}
}
);
export default class App extends Component {
render() {
return <x-foo position={{ x: 10, y: 20 }}>foo bar</x-foo>;
}
}
if (typeof window !== "undefined") {
render(<App />, document.getElementById("root"));
}
We add the position
setter.
Then we set the this.style.cssText
property to set the position of the x-foo
component.
Therefore, the x-foo
component has the position values applied to it.
We can also call methods in web component classes.
To do this, we assign a ref to the web component.
Then we can call the methods in the web component class:
import { render } from "preact";
import { useEffect, useRef } from "preact/hooks";
window.customElements.define(
"x-foo",
class extends HTMLElement {
constructor() {
super();
let tmpl = document.createElement("template");
tmpl.innerHTML = `
<b>I am in the shadown dom</b>
<slot></slot>
`;
let shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(tmpl.content.cloneNode(true));
}
set position({ x, y }) {
this.style.cssText = `left:${x}px; top:${y}px; position: absolute`;
}
doSomething() {
console.log("did something");
}
}
);
export default function App() {
const myRef = useRef(null);
useEffect(() => {
if (myRef.current) {
myRef.current.doSomething();
}
}, []);
return <x-foo ref={myRef} />;
}
if (typeof window !== "undefined") {
render(<App />, document.getElementById("root"));
}
We set the ref
prop to the myRef
ref object, which is created from the useRef
hook.
Then in the useEffect
callback, we call myRef.current.doSomething()
method to call the doSomething
method in the web component.
Listen to Web Component Events
We can listen to web components. For example, we can write:
import { render } from "preact";
import { useEffect, useRef } from "preact/hooks";
window.customElements.define(
"x-foo",
class extends HTMLElement {
constructor() {
super();
let tmpl = document.createElement("template");
tmpl.innerHTML = `
<b>I am in the shadown dom</b>
<slot></slot>
`;
let shadowRoot = this.attachShadow({ mode: "open" });
shadowRoot.appendChild(tmpl.content.cloneNode(true));
}
set position({ x, y }) {
this.style.cssText = `left:${x}px; top:${y}px; position: absolute`;
}
connectedCallback() {
this.shadowRoot.addEventListener("click", function (e) {
console.log("listend to click event");
console.log(e);
});
}
}
);
export default function App() {
return <x-foo onclick={() => console.log("click")}>foo bar</x-foo>;
}
if (typeof window !== "undefined") {
render(<App />, document.getElementById("root"));
}
We call addEventListener
to add the click event listener to our web component.
And we set the onclick
prop to assign an event listener for the click
event.
So when we click on the text, we should see the console log from both event listeners called.
Conclusion
We can use web components directly in our Preact app.